package sf.r2dbc.type;

import io.r2dbc.spi.Row;
import io.r2dbc.spi.Statement;
import io.r2dbc.spi.Type;

public class R2dbcTypeHandlerImpl<T> implements R2dbcTypeHandler<T> {
    private Class<T> clazz;
    private Type type;

    public R2dbcTypeHandlerImpl(Class<T> clazz, Type type) {
        this.clazz = clazz;
        this.type = type;
        if (clazz == null) {
            clazz = (Class<T>) Object.class;
        }
    }

    @Override
    public T get(Row rs, String columnLabel) {
        return rs.get(columnLabel, clazz);
    }

    @Override
    public T get(Row rs, int columnIndex) {
        return rs.get(columnIndex, clazz);
    }

    @Override
    public Statement set(Statement statement, Object value, Class<?> targetClass, int index) {
        if (value == null) {
            if (targetClass != null) {
                return statement.bindNull(index, targetClass);
            } else {
                return statement.bindNull(index, Object.class);
            }
        }
        return statement.bind(index, value);
    }

    @Override
    public Statement set(Statement statement, Object value, Class<?> targetClass, String parameterName) {
        if (value == null) {
            if (targetClass != null) {
                return statement.bindNull(parameterName, targetClass);
            } else {
                return statement.bindNull(parameterName, Object.class);
            }
        }
        return statement.bind(parameterName, value);
    }

    @Override
    public Class<T> getDefaultJavaType() {
        return clazz;
    }

    @Override
    public Type getSqlType() {
        return type;
    }
}
